<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>2021前端vue面试题 | 七里香</title><meta name="keywords" content="面试"><meta name="author" content="william"><meta name="copyright" content="william"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="1. 什么是 MVVM？ MVVM 是Model-View-ModelView的缩写，是一种脱胎于 MVC 模式的设计模式。 Model 代表数据层，负责存放业务相关的数据； View 代表视图层，负责在页面上展示数据； ViewModel 是的作用是同步 View 和 Model 之间的关联，其实现同步关联的核心是DOM Listeners和 Data Bindings两个工具。DOMListe">
<meta property="og:type" content="article">
<meta property="og:title" content="2021前端vue面试题">
<meta property="og:url" content="http://yokeney.gitee.io/my-hexo-blog/2021/03/15/vuepre/index.html">
<meta property="og:site_name" content="七里香">
<meta property="og:description" content="1. 什么是 MVVM？ MVVM 是Model-View-ModelView的缩写，是一种脱胎于 MVC 模式的设计模式。 Model 代表数据层，负责存放业务相关的数据； View 代表视图层，负责在页面上展示数据； ViewModel 是的作用是同步 View 和 Model 之间的关联，其实现同步关联的核心是DOM Listeners和 Data Bindings两个工具。DOMListe">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://yokeney.gitee.io/my-hexo-blog/img/vuepre.png">
<meta property="article:published_time" content="2021-03-15T13:33:31.000Z">
<meta property="article:modified_time" content="2022-10-15T13:35:30.552Z">
<meta property="article:author" content="william">
<meta property="article:tag" content="面试">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://yokeney.gitee.io/my-hexo-blog/img/vuepre.png"><link rel="shortcut icon" href="/my-hexo-blog/img/index.ico"><link rel="canonical" href="http://yokeney.gitee.io/my-hexo-blog/2021/03/15/vuepre/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/my-hexo-blog/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.min.css" media="print" onload="this.media='all'"><script>const GLOBAL_CONFIG = { 
  root: '/my-hexo-blog/',
  algolia: undefined,
  localSearch: {"path":"/my-hexo-blog/search.xml","preload":false,"languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: undefined,
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  lightbox: 'fancybox',
  Snackbar: undefined,
  source: {
    justifiedGallery: {
      js: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.js',
      css: 'https://cdn.jsdelivr.net/npm/flickr-justified-gallery/dist/fjGallery.min.css'
    }
  },
  isPhotoFigcaption: false,
  islazyload: false,
  isAnchor: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
  title: '2021前端vue面试题',
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isToc: true,
  postUpdate: '2022-10-15 21:35:30'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(win=>{
    win.saveToLocal = {
      set: function setWithExpiry(key, value, ttl) {
        if (ttl === 0) return
        const now = new Date()
        const expiryDay = ttl * 86400000
        const item = {
          value: value,
          expiry: now.getTime() + expiryDay,
        }
        localStorage.setItem(key, JSON.stringify(item))
      },

      get: function getWithExpiry(key) {
        const itemStr = localStorage.getItem(key)

        if (!itemStr) {
          return undefined
        }
        const item = JSON.parse(itemStr)
        const now = new Date()

        if (now.getTime() > item.expiry) {
          localStorage.removeItem(key)
          return undefined
        }
        return item.value
      }
    }
  
    win.getScript = url => new Promise((resolve, reject) => {
      const script = document.createElement('script')
      script.src = url
      script.async = true
      script.onerror = reject
      script.onload = script.onreadystatechange = function() {
        const loadState = this.readyState
        if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
        script.onload = script.onreadystatechange = null
        resolve()
      }
      document.head.appendChild(script)
    })
  
      win.activateDarkMode = function () {
        document.documentElement.setAttribute('data-theme', 'dark')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
        }
      }
      win.activateLightMode = function () {
        document.documentElement.setAttribute('data-theme', 'light')
        if (document.querySelector('meta[name="theme-color"]') !== null) {
          document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
        }
      }
      const t = saveToLocal.get('theme')
    
          if (t === 'dark') activateDarkMode()
          else if (t === 'light') activateLightMode()
        
      const asideStatus = saveToLocal.get('aside-status')
      if (asideStatus !== undefined) {
        if (asideStatus === 'hide') {
          document.documentElement.classList.add('hide-aside')
        } else {
          document.documentElement.classList.remove('hide-aside')
        }
      }
    
    const detectApple = () => {
      if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
        document.documentElement.classList.add('apple')
      }
    }
    detectApple()
    })(window)</script><meta name="generator" content="Hexo 6.3.0"></head><body><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src="/my-hexo-blog/img/2.png" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="sidebar-site-data site-data is-center"><a href="/my-hexo-blog/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/my-hexo-blog/tags/"><div class="headline">标签</div><div class="length-num">13</div></a><a href="/my-hexo-blog/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/my-hexo-blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/vueResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> vue</span></a></li><li><a class="site-page child" href="/my-hexo-blog/reactResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> react</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-shenghuo"></i><span> 后台</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/nodeResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> node</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image: url('/my-hexo-blog/img/vuepre.png')"><nav id="nav"><span id="blog_name"><a id="site-name" href="/my-hexo-blog/">七里香</a></span><div id="menus"><div id="search-button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/my-hexo-blog/"><i class="fa-fw iconfont icon-shouyex"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-zuixinwenzhang_huaban"></i><span> 分类</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/vueResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> vue</span></a></li><li><a class="site-page child" href="/my-hexo-blog/reactResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> react</span></a></li></ul></div><div class="menus_item"><a class="site-page group" href="javascript:void(0);"><i class="fa-fw iconfont icon-shenghuo"></i><span> 后台</span><i class="fas fa-chevron-down"></i></a><ul class="menus_item_child"><li><a class="site-page child" href="/my-hexo-blog/nodeResources/"><i class="fa-fw iconfont icon-fenlei1"></i><span> node</span></a></li></ul></div></div><div id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></div></div></nav><div id="post-info"><h1 class="post-title">2021前端vue面试题</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2021-03-15T13:33:31.000Z" title="发表于 2021-03-15 21:33:31">2021-03-15</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2022-10-15T13:35:30.552Z" title="更新于 2022-10-15 21:35:30">2022-10-15</time></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" id="" data-flag-title="2021前端vue面试题"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><article class="post-content" id="article-container"><h3 id="1-什么是-MVVM？"><a href="#1-什么是-MVVM？" class="headerlink" title="1. 什么是 MVVM？"></a>1. 什么是 MVVM？</h3><ul>
<li>MVVM 是Model-View-ModelView的缩写，是一种脱胎于 MVC 模式的设计模式。</li>
<li>Model 代表数据层，负责存放业务相关的数据；</li>
<li>View 代表视图层，负责在页面上展示数据；</li>
<li><code>ViewModel 是的作用是同步 View 和 Model 之间的关联，其实现同步关联的核心是DOM Listeners和 Data Bindings两个工具。DOMListeners 工具用于监听 View 中 DOM 的变化，并会选择性的传给 Model；Data Bindings 工具用于监听 Model 数据变化，并将其更新给 View。</code></li>
</ul>
<h3 id="2-组件通讯"><a href="#2-组件通讯" class="headerlink" title="2.组件通讯"></a>2.组件通讯</h3><h4 id="父传子"><a href="#父传子" class="headerlink" title="父传子"></a>父传子</h4><blockquote>
<p>父传子利用props</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">**父组件代码**</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">header-box</span> <span class="attr">:title-txt</span>=<span class="string">&quot;showTitleTxt&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">header-box</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">import</span> <span class="title class_">Header</span> <span class="keyword">from</span> <span class="string">&#x27;./header&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">name</span>: <span class="string">&#x27;index&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">components</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="string">&#x27;header-box&#x27;</span>: <span class="title class_">Header</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        data () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="attr">showTitleTxt</span>: <span class="string">&#x27;首页&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**子组件代码**</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">header</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        &#123;&#123;thisTitleTxt&#125;&#125;</span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">header</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">name</span>: <span class="string">&#x27;header-box&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">props</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="attr">titleTxt</span>: <span class="title class_">String</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        data () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="attr">thisTitleTxt</span>: <span class="variable language_">this</span>.<span class="property">titleTxt</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<h4 id="子传父"><a href="#子传父" class="headerlink" title="子传父"></a>子传父</h4><p>利用on和 on和on和emit 即子组件利用一个事件来触发$emit来传递出去一个事件及参数，然后在父组件里绑定这个事件，然后处理这个事件，获取传递的参数<br>子组件改变父组件传递的props（你会发现通过props可传递复杂类型数据，可以通过子组件改变数据内容，不推荐使用，因为vue是规定props是单向绑定）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">*通过$on,$emit*</span><br><span class="line">**父组件代码**</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;counter-event-example&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;&#123; total &#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">      <span class="tag">&lt;<span class="name">button-counter</span> <span class="attr">v-on:increment</span>=<span class="string">&quot;incrementTotal&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">button-counter</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">import</span> <span class="title class_">ButtonCounter</span> <span class="keyword">from</span> <span class="string">&#x27;./buttonCounter&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">name</span>: <span class="string">&#x27;index&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">components</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="string">&#x27;button-conuter&#x27;</span>: <span class="title class_">ButtonCounter</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        data () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="attr">total</span>: <span class="number">0</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            incrementTotal () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="variable language_">this</span>.<span class="property">total</span>++</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">**子组件代码**</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;incrementCounter&quot;</span>&gt;</span>&#123;&#123;counter&#125;&#125;<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;/<span class="name">template</span>&gt;</span></span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">name</span>: <span class="string">&#x27;button-counter&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        data () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="attr">counter</span>: <span class="number">0</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">metheds</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            incrementCounter () &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="variable language_">this</span>.$emit(<span class="string">&#x27;increment&#x27;</span>)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">                <span class="variable language_">this</span>.<span class="property">counter</span>++</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<h4 id="非父子"><a href="#非父子" class="headerlink" title="非父子"></a>非父子</h4><p><strong>创建一个空的vue实例，然后挂载到当前的vue实例的原型上,然后一个组件进行e m i t 传 递 事 件 以 及 需 要 传 递 的 数 据 。 在 另 一 个 组 件 那 里 就 可 以 进 行 使 用 emit传递事件以及需要传递的数据。在另一个组件那里就可以进行使用emit传递事件以及需要传递的数据。在另一个组件那里就可以进行使用on来接受这个事件并处理这个传递参数</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> bus =<span class="keyword">new</span> <span class="title class_">Vue</span>()</span><br><span class="line"><span class="title class_">Vue</span>.<span class="property"><span class="keyword">prototype</span></span>.<span class="property">bus</span> = bus</span><br></pre></td></tr></table></figure>
<h4 id="vuex"><a href="#vuex" class="headerlink" title="vuex"></a>vuex</h4><h3 id="3-生命周期"><a href="#3-生命周期" class="headerlink" title="3.生命周期"></a>3.生命周期</h3><p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/84bd56f4844046c1bae661d2debe9388~tplv-k3u1fbpfcp-watermark.image" alt="v2-5c29f94ef025b036a8c9b5cea3b39a50_1440w.jpg"></p>
<ul>
<li>beforeCreate：vue实例的挂载元素el和数据对象data都是undefined，还没用初始化</li>
<li>created：vue实例的数据对象data有了，可以访问里面的数据和方法，未挂载到DOM，el还没有</li>
<li>beforeMount：vue实例的el和data都初始化了，但是挂载之前未虚拟DOM节点</li>
<li>mounted：vue实例挂载到真实DOM上，就可以通过DOM获取DOM节点</li>
<li>beforeupdated：响应式数据更新时调用，发生在虚拟DOM打补丁之前，适合在更新之前访问现有的DOM，比如手动一处已添加的事件监听器</li>
<li>updated：虚拟DOM重新渲染和打补丁之后调用，组成新的DOM已经更新，避免在这个钩子函数中操作数据，防止死循环</li>
<li>beforeDestroy：实例销毁前调用，实例还可以用，this能获取到实例，常用于销毁定时器，解绑事件</li>
<li>destroyed：实例销毁后调用，调用后所有事件监听器会被移除，所有的子实例都会被销毁</li>
</ul>
<h3 id="4-vue组件中data必须是一个函数"><a href="#4-vue组件中data必须是一个函数" class="headerlink" title="4.vue组件中data必须是一个函数"></a>4.vue组件中data必须是一个函数</h3><blockquote>
<p>如果 data 是一个对象，当复用组件时，因为 data 都会指向同一个引用类型地址，其中一个组件的 &gt; data 一旦发生修改，则其他重用的组件中的 data 也会被一并修改。<br>如果 data 是一个返回对象的函数，因为每次重用组件时返回的都是一个新对象，引用地址不同，便不&gt; 会出现如上问题。</p>
</blockquote>
<h3 id="5-Vue-中-v-if-和-v-show-有什么区别？"><a href="#5-Vue-中-v-if-和-v-show-有什么区别？" class="headerlink" title="5.Vue 中 v-if 和 v-show 有什么区别？"></a>5.Vue 中 v-if 和 v-show 有什么区别？</h3><p>v-if 在进行切换时，会直接对标签进行创建或销毁，不显示的标签不会加载在 DOM 树中。v-show 在进行切换时，会对标签的 display 属性进行切换，通过 display 不显示来隐藏元素。<br>一般来说，v-if 的性能开销会比 v-show 大，切换频繁的标签更适合使用 v-show。</p>
<h3 id="6-Vue-中-computed-和-watch-有什么区别？"><a href="#6-Vue-中-computed-和-watch-有什么区别？" class="headerlink" title="6.Vue 中 computed 和 watch 有什么区别？"></a>6.Vue 中 computed 和 watch 有什么区别？</h3><p><strong>计算属性 computed：</strong></p>
<ol>
<li>支持缓存，只有依赖数据发生变化时，才会重新进行计算函数；</li>
<li>计算属性内不支持异步操作；</li>
<li>计算属性的函数中都有一个 get(默认具有，获取计算属性)和 set(手动添加，设置计算属性)方法；</li>
<li>计算属性是自动监听依赖值的变化，从而动态返回内容。</li>
</ol>
<p><strong>侦听属性 watch：</strong></p>
<ol>
<li>不支持缓存，只要数据发生变化，就会执行侦听函数；</li>
<li>侦听属性内支持异步操作；</li>
<li>侦听属性的值可以是一个对象，接收 handler 回调，deep，immediate 三个属性；</li>
<li>监听是一个过程，在监听的值变化时，可以触发一个回调，并做一些其他事情。</li>
</ol>
<h3 id="7-nextTick-是什么"><a href="#7-nextTick-是什么" class="headerlink" title="7.$nextTick 是什么"></a>7.$nextTick 是什么</h3><p>Vue 实现响应式并不是在数据发生后立即更新 DOM，使用 vm.$nextTick 是在下次 DOM 更新循环结束之后立即执行延迟回调。在修改数据之后使用，则可以在回调中获取更新后的 DOM。</p>
<h3 id="8-v-for-中-key-的作用是什么？"><a href="#8-v-for-中-key-的作用是什么？" class="headerlink" title="8. v-for 中 key 的作用是什么？"></a>8. v-for 中 key 的作用是什么？</h3><p>key 是 Vue 使用 v-for 渲染列表时的节点标识。使用了 key 之后，当列表项发生变化时，Vue 会基于 key 的变化而重新排列元素顺序，并且移除 key 不存在的元素，提升运行效率。</p>
<h3 id="9-Vue-的双向数据绑定原理是什么？"><a href="#9-Vue-的双向数据绑定原理是什么？" class="headerlink" title="9. Vue 的双向数据绑定原理是什么？"></a>9. Vue 的双向数据绑定原理是什么？</h3><ul>
<li>Vue 采用数据劫持+订阅发布模式实现双向绑定。通过 Object.defineProperty()方法来为组件中 data 的每个属性添加 get 和 set 方法，在数据变动时，触发 set 里相应的监听回调函数，将变动信息发布给订阅者。主要有以下步骤：</li>
</ul>
<p>组件初始化时：</p>
<ol>
<li><code>创建一个dep 对象作为观察者（依赖收集、订阅发布的载体）；</code></li>
<li><code>通过Object.defineProperty()方法对 data 中的属性及子属性对象的属性，添加 getter 和 setter 方法； 调用 getter 时，便去 dep 里注册函数。调用 setter 时，便去通知执行刚刚注册的函数。</code></li>
<li><code>组件挂载时</code>：</li>
<li><code>compile解析模板指令，将其中的变量替换成数据。然后初始化渲染页面视图，并将每个指令对应的节点绑定上更新函数、监听函数。后续一旦数据发生变化，便会更新页面。页面发生变化时也会相应发布变动信息；</code></li>
<li><code>组件同时会定义一个watcher 类作为订阅者，watcher 可以视作 dep 和组件之间的桥梁。其在实例化时会向 dep 中添加自己，同时自身又有一个 update 方法，待收到 dep 的变动通知时，便会调用自己的 update 方法，触发 compile 中的相应函数完成更新。</code></li>
</ol>
<h3 id="10-如何动态更新对象或数组的值？"><a href="#10-如何动态更新对象或数组的值？" class="headerlink" title="10.如何动态更新对象或数组的值？"></a>10.如何动态更新对象或数组的值？</h3><p>因为 Object.defineProperty()的限制，Vue 无法监听到对象或数组内部某个属性值的变化，因此在直接设置以上两类数据的值时，页面不会实时更新。此时可以通过 this.$set 方法来解决：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="variable language_">this</span>.$set(要改变的数组/对象，要改变的位置/key，要改成的value)</span><br><span class="line"></span><br><span class="line"><span class="variable language_">this</span>.$set(<span class="variable language_">this</span>.<span class="property">arr</span>, <span class="number">0</span>, <span class="string">&quot;OBKoro1&quot;</span>);</span><br><span class="line"><span class="comment">// 改变数组 </span></span><br><span class="line"><span class="variable language_">this</span>.$set(<span class="variable language_">this</span>.<span class="property">obj</span>, <span class="string">&quot;c&quot;</span>, <span class="string">&quot;OBKoro1&quot;</span>); <span class="comment">// 改变对象</span></span><br><span class="line">数组原生方法造成的数据更新，可以被 <span class="title class_">Vue</span> 监听到。如 <span class="title function_">splice</span>()<span class="title function_">push</span>()<span class="title function_">pop</span>()等。</span><br></pre></td></tr></table></figure>
<h3 id="11-常用的事件修饰符有哪些？"><a href="#11-常用的事件修饰符有哪些？" class="headerlink" title="11.常用的事件修饰符有哪些？"></a>11.常用的事件修饰符有哪些？</h3><ul>
<li>.stop：阻止冒泡；</li>
<li>.prevent：阻止默认行为；</li>
<li>.self：仅绑定元素自身可触发；</li>
<li>.once：只触发一次..</li>
</ul>
<h3 id="12-Vue-如何获取-DOM-元素？"><a href="#12-Vue-如何获取-DOM-元素？" class="headerlink" title="12.Vue 如何获取 DOM 元素？"></a>12.Vue 如何获取 DOM 元素？</h3><blockquote>
<p>首先先为标签元素设置 ref 属性，然后通过 this.$refs.属性值获取。</p>
</blockquote>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;div ref=<span class="string">&quot;test&quot;</span>&gt;&lt;/div&gt; <span class="keyword">const</span> dom = <span class="variable language_">this</span>.<span class="property">$refs</span>.<span class="property">test</span></span><br></pre></td></tr></table></figure>
<h3 id="13-v-on-如何绑定多个事件？"><a href="#13-v-on-如何绑定多个事件？" class="headerlink" title="13.v-on 如何绑定多个事件？"></a>13.v-on 如何绑定多个事件？</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&lt;input type=<span class="string">&quot;text&quot;</span> v-on=<span class="string">&quot;&#123; input:onInput,focus:onFocus,blur:onBlur &#125;&quot;</span>&gt;</span><br></pre></td></tr></table></figure>
<h3 id="14-Vue-初始化页面闪动问题如何解决？"><a href="#14-Vue-初始化页面闪动问题如何解决？" class="headerlink" title="14.Vue 初始化页面闪动问题如何解决？"></a>14.Vue 初始化页面闪动问题如何解决？</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">出现该问题是因为在 <span class="title class_">Vue</span> 代码尚未被解析之前，尚无法控制页面中 <span class="variable constant_">DOM</span> 的显示，所以会看见模板字符串等代码。 解决方案是，在 css 代码中添加 v-cloak 规则，同时在待编译的标签上添加 v-cloak 属性：</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[v-cloak] &#123; <span class="attr">display</span>: none; &#125; &lt;div v-cloak&gt; &#123;&#123; message &#125;&#125; &lt;/div&gt;</span><br></pre></td></tr></table></figure>
<h3 id="15-Vue-如何清除浏览器缓存？"><a href="#15-Vue-如何清除浏览器缓存？" class="headerlink" title="15.Vue 如何清除浏览器缓存？"></a>15.Vue 如何清除浏览器缓存？</h3><ol>
<li>项目打包的时候给每个打包文件加上 hash 值，一般是在文件后面加上时间戳；</li>
<li>在 html 文件中加入 meta 标签，content 属性设置为no-cache;</li>
<li>在后端服务器中进行禁止缓存设置。</li>
</ol>
<h3 id="16-Vue-router-路由有哪些模式？"><a href="#16-Vue-router-路由有哪些模式？" class="headerlink" title="16.Vue-router 路由有哪些模式？"></a>16.Vue-router 路由有哪些模式？</h3><ul>
<li><p>hash 模式：后面的 hash 值的变化，浏览器既不会向服务器发出请求，浏览器也不会刷新，每次 hash 值的变化会触发 hashchange 事件。</p>
</li>
<li><p>history 模式：利用了 HTML5 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器的历史记录栈，在当前已有的 back、forward、go 的基础之上，它们提供了对历史记录进行修改的功能。只是当它们执行修改时，虽然改变了当前的 URL，但浏览器不会立即向后端发送请求。</p>
</li>
<li><p>hash 模式：后面的 hash 值的变化，浏览器既不会向服务器发出请求，浏览器也不会刷新，每次 hash 值的变化会触发 hashchange 事件。</p>
</li>
</ul>
<hr>
<p><code>history 模式：利用了 HTML5 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器的历史记录栈，在当前已有的 back、forward、go 的基础之上，它们提供了对历史记录进行修改的功能。只是当它们执行修改时，虽然改变了当前的 URL，但浏览器不会立即向后端发送请求。</code></p>
<h3 id="18-Vuex-是什么？有哪几种属性？"><a href="#18-Vuex-是什么？有哪几种属性？" class="headerlink" title="18.Vuex 是什么？有哪几种属性？"></a>18.Vuex 是什么？有哪几种属性？</h3><p><strong>Vuex 是专为Vue设计的状态管理工具，采用集中式储存管理 Vue 中所有组件的状态。</strong></p>
<ul>
<li><code>state属性：基本数据；</code></li>
<li><code>getters属性：从 state 中派生出的数据；</code></li>
<li><code>mutation属性：更新 store 中数据的唯一途径，其接收一个以 state 为第一参数的回调函数；</code><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> store = <span class="keyword">new</span> <span class="title class_">Vuex</span>.<span class="title class_">Store</span>(&#123;</span><br><span class="line">  <span class="attr">state</span>: &#123;</span><br><span class="line">    <span class="attr">count</span>: <span class="number">1</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">mutations</span>: &#123;</span><br><span class="line">    <span class="title function_">increment</span>(<span class="params">state</span>) &#123;</span><br><span class="line">      <span class="comment">// 变更状态</span></span><br><span class="line">      state.<span class="property">count</span>++;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> store = <span class="keyword">new</span> <span class="title class_">Vuex</span>.<span class="title class_">Store</span>(&#123;</span><br><span class="line">  <span class="attr">state</span>: &#123;</span><br><span class="line">    <span class="attr">count</span>: <span class="number">0</span>,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">mutations</span>: &#123;</span><br><span class="line">    <span class="title function_">increment</span>(<span class="params">state</span>) &#123;</span><br><span class="line">      state.<span class="property">count</span>++;</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="attr">actions</span>: &#123;</span><br><span class="line">    <span class="title function_">increment2</span>(<span class="params">context</span>) &#123;</span><br><span class="line">      context.<span class="title function_">commit</span>(<span class="string">&#x27;increment&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="title function_">fun</span>(<span class="params">context</span>) &#123;</span><br><span class="line">      context.<span class="title function_">dispatch</span>(<span class="string">&#x27;increment2&#x27;</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;,</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></li>
</ul>
<ol start="5">
<li>module 属性：用于将 store分割成不同的模块。</li>
</ol>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> moduleA = &#123;</span><br><span class="line">  <span class="attr">state</span>: <span class="function">() =&gt;</span> (&#123; ... &#125;),</span><br><span class="line">  <span class="attr">mutations</span>: &#123; ... &#125;,</span><br><span class="line">  <span class="attr">actions</span>: &#123; ... &#125;,</span><br><span class="line">  <span class="attr">getters</span>: &#123; ... &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> moduleB = &#123;</span><br><span class="line">  <span class="attr">state</span>: <span class="function">() =&gt;</span> (&#123; ... &#125;),</span><br><span class="line">  <span class="attr">mutations</span>: &#123; ... &#125;,</span><br><span class="line">  <span class="attr">actions</span>: &#123; ... &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> store = <span class="keyword">new</span> <span class="title class_">Vuex</span>.<span class="title class_">Store</span>(&#123;</span><br><span class="line">  <span class="attr">modules</span>: &#123;</span><br><span class="line">    <span class="attr">a</span>: moduleA,</span><br><span class="line">    <span class="attr">b</span>: moduleB</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line">store.<span class="property">state</span>.<span class="property">a</span> <span class="comment">// -&gt; moduleA 的状态</span></span><br><span class="line">store.<span class="property">state</span>.<span class="property">b</span> <span class="comment">// -&gt; moduleB 的状态</span></span><br></pre></td></tr></table></figure>
<h3 id="19-说一下v-model的原理"><a href="#19-说一下v-model的原理" class="headerlink" title="19.说一下v-model的原理"></a>19.说一下v-model的原理</h3><p><strong><code>v-model本质就是一个语法糖，可以看成是value + input方法的语法糖。 可以通过model属性的prop和event属性来进行自定义。原生的v-model，会根据标签的不同生成不同的事件和属性。</code></strong></p>
<p><strong>作用在表单元素上</strong> 动态绑定了 input 的 value 指向了 messgae 变量，并且在触发 input 事件的时候去动态把 message设置为目标值：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">&lt;input v-model=<span class="string">&quot;sth&quot;</span> /&gt;</span><br><span class="line"><span class="comment">//  等同于</span></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">input</span> </span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">v-bind:value</span>=<span class="string">&quot;message&quot;</span> </span></span></span><br><span class="line"><span class="tag"><span class="language-xml">    <span class="attr">v-on:input</span>=<span class="string">&quot;message=$event.target.value&quot;</span></span></span></span><br><span class="line"><span class="tag"><span class="language-xml">&gt;</span></span></span><br><span class="line"><span class="language-xml">//$event 指代当前触发的事件对象;</span></span><br><span class="line"><span class="language-xml">//$event.target 指代当前触发的事件对象的dom;</span></span><br><span class="line"><span class="language-xml">//$event.target.value 就是当前dom的value值;</span></span><br><span class="line"><span class="language-xml">//在@input方法中，value =&gt; sth;</span></span><br><span class="line"><span class="language-xml">//在:value中,sth =&gt; value;</span></span><br></pre></td></tr></table></figure>

<h3 id="20-Vue模版编译原理知道吗，能简单说一下吗？"><a href="#20-Vue模版编译原理知道吗，能简单说一下吗？" class="headerlink" title="20.Vue模版编译原理知道吗，能简单说一下吗？"></a>20.Vue模版编译原理知道吗，能简单说一下吗？</h3><p>简单说，Vue的编译过程就是将template转化为render函数的过程。会经历以下阶段：</p>
<ul>
<li>生成AST树</li>
<li>优化</li>
<li>codegen<br>首先解析模版，生成AST语法树(一种用JavaScript对象的形式来描述整个模板)。<br>使用大量的正则表达式对模板进行解析，遇到标签、文本的时候都会执行对应的钩子进行相关处理。</li>
</ul>
<p>Vue的数据是响应式的，但其实模板中并不是所有的数据都是响应式的。有一些数据首次渲染后就不会再变化，对应的DOM也不会变化。那么优化过程就是深度遍历AST树，按照相关条件对树节点进行标记。这些被标记的节点(静态节点)我们就可以跳过对它们的比对，对运行时的模板起到很大的优化作用。</p>
<p>编译的最后一步是将优化后的AST树转换为可执行的代码。</p>
<h3 id="21-Vue中组件生命周期调用顺序"><a href="#21-Vue中组件生命周期调用顺序" class="headerlink" title="21.Vue中组件生命周期调用顺序"></a>21.Vue中组件生命周期调用顺序</h3><ul>
<li>组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。</li>
<li>组件的销毁操作是先父后子，销毁完成的顺序是先子后父。</li>
</ul>
<h4 id="加载渲染过程"><a href="#加载渲染过程" class="headerlink" title="加载渲染过程"></a>加载渲染过程</h4><p><code>父beforeCreate-&gt;父created-&gt;父beforeMount-&gt;子beforeCreate-&gt;子created-&gt;子beforeMount- &gt;子mounted-&gt;父mounted</code></p>
<h4 id="子组件更新过程"><a href="#子组件更新过程" class="headerlink" title="子组件更新过程"></a>子组件更新过程</h4><p><code>父 beforeUpdate -&gt; 父 updated</code></p>
<h4 id="销毁过程"><a href="#销毁过程" class="headerlink" title="销毁过程"></a>销毁过程</h4><p><code>父beforeDestroy-&gt;子beforeDestroy-&gt;子destroyed-&gt;父destroyed</code></p>
<h2 id="vue-router有哪几种导航钩子？"><a href="#vue-router有哪几种导航钩子？" class="headerlink" title="vue-router有哪几种导航钩子？"></a>vue-router有哪几种导航钩子？</h2><ol>
<li>全局导航钩子：router.beforeEach(to,from,next)</li>
<li>组件内的钩子beforeRouteEnter (to, from, next) beforeRouteUpdate (to, from, next) beforeRouteLeave (to, from, next)</li>
<li>单独路由独享组件 beforeEnter: (to, from, next)</li>
</ol>
<h3 id="22-你都做过哪些Vue的性能优化"><a href="#22-你都做过哪些Vue的性能优化" class="headerlink" title="22.你都做过哪些Vue的性能优化"></a>22.你都做过哪些Vue的性能优化</h3><h4 id="编码阶段"><a href="#编码阶段" class="headerlink" title="编码阶段"></a>编码阶段</h4><ol>
<li>尽量减少data中的数据，data中的数据都会增加getter和setter，会收集对应的watcher</li>
<li>v-if和v-for不能连用</li>
<li>如果需要使用v-for给每项元素绑定事件时使用事件代理</li>
<li>SPA 页面采用keep-alive缓存组件</li>
<li>在更多的情况下，使用v-if替代v-show</li>
<li>key保证唯一</li>
<li>使用路由懒加载、异步组件</li>
<li>防抖、节流第三方模块按需导入</li>
<li>长列表滚动到可视区域动态加载</li>
<li>图片懒加载<br>这里附上：<br><img src="https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/37969f1c2dba49da8517879c1bf0cf6d~tplv-k3u1fbpfcp-watermark.image" alt="vue  项目优化解析.png"><br><strong>23.自定义指令基本内容</strong></li>
</ol>
<ul>
<li>全局定义：<code>Vue.directive(&quot;focus&quot;,&#123;&#125;)</code></li>
<li>局部定义：<code>directives:&#123;focus:&#123;&#125;&#125;</code></li>
<li>钩子函数：指令定义对象提供钩子函数</li>
</ul>
<ol>
<li><code>bind：只调用一次，指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。</code></li>
<li><code>inSerted：被绑定元素插入父节点时调用（仅保证父节点存在，但不一定已被插入文档中）。</code></li>
<li><code>update：所在组件的VNode更新时调用，但是可能发生在其子VNode更新之前调用。指令的值可能发生了改变，也可能没有。但是可以通过比较更新前后的值来忽略不必要的模板更新。</code></li>
<li><code>ComponentUpdate：指令所在组件的 VNode及其子VNode全部更新后调用。</code></li>
<li><code>unbind：只调用一次，指令与元素解绑时调用</code><br><strong>使用场景</strong></li>
</ol>
<ul>
<li>普通DOM元素进行底层操作的时候，可以使用自定义指令</li>
<li>自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念，但并非所有情况都适合数据驱动。自定义指令就是一种有效的补充和扩展，不仅可用于定义任何的DOM操作，并且是可复用的。<br><strong>使用案例</strong><br>初级应用：</li>
<li>鼠标聚焦</li>
<li>下拉菜单</li>
<li>相对时间转换</li>
<li>滚动动画<br>高级应用：</li>
<li>自定义指令实现图片懒加载</li>
<li>自定义指令集成第三方插件</li>
</ul>
<h3 id="24-Vue是如何收集依赖的？"><a href="#24-Vue是如何收集依赖的？" class="headerlink" title="24.Vue是如何收集依赖的？"></a>24.Vue是如何收集依赖的？</h3><pre><code>在初始化 Vue 的每个组件时，会对组件的 data 进行初始化，就会将由普通对象变成响应式对象，在这个过程中便会进行依赖收集的相关逻辑，如下所示∶
</code></pre>
 <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Dep</span> &#123;</span><br><span class="line">  <span class="keyword">static</span> target;</span><br><span class="line">  subs;</span><br><span class="line"></span><br><span class="line">  <span class="title function_">constructor</span> () &#123;</span><br><span class="line">    ...</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">subs</span> = [];</span><br><span class="line">  &#125;</span><br><span class="line">  addSub (sub) &#123;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">subs</span>.<span class="title function_">push</span>(sub)</span><br><span class="line">  &#125;</span><br><span class="line">  removeSub (sub) &#123;</span><br><span class="line">    <span class="title function_">remove</span>(<span class="variable language_">this</span>.<span class="property">sub</span>, sub)</span><br><span class="line">  &#125;</span><br><span class="line">  depend () &#123;</span><br><span class="line">    <span class="keyword">if</span>(<span class="title class_">Dep</span>.<span class="property">target</span>)&#123;</span><br><span class="line">      <span class="title class_">Dep</span>.<span class="property">target</span>.<span class="title function_">addDep</span>(<span class="variable language_">this</span>)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  notify () &#123;</span><br><span class="line">    <span class="keyword">const</span> subs = <span class="variable language_">this</span>.<span class="property">subds</span>.<span class="title function_">slice</span>();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">let</span> i = <span class="number">0</span>;i &lt; subs.<span class="property">length</span>; i++)&#123;</span><br><span class="line">      subs[i].<span class="title function_">update</span>()</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>Dep 是一个 class ，其中有一个关 键的静态属性 static，它指向了一个全局唯一 Watcher，保证了同一时间全局只有一个 watcher 被计算，另一个属性 subs 则是一个 Watcher 的数组，所以 Dep 实际上就是对 Watcher 的管理，再看看 Watcher 的相关代码∶</strong></p>
<h3 id="Watcher"><a href="#Watcher" class="headerlink" title="Watcher"></a><strong>Watcher</strong></h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Watcher</span> &#123;</span><br><span class="line">  getter;</span><br><span class="line">  ...</span><br><span class="line">  <span class="title function_">constructor</span> (vm, expression)&#123;</span><br><span class="line">    ...</span><br><span class="line">    <span class="variable language_">this</span>.<span class="property">getter</span> = expression;</span><br><span class="line">    <span class="variable language_">this</span>.<span class="title function_">get</span>();</span><br><span class="line">  &#125;</span><br><span class="line">  get () &#123;</span><br><span class="line">    <span class="title function_">pushTarget</span>(<span class="variable language_">this</span>);</span><br><span class="line">    value = <span class="variable language_">this</span>.<span class="property">getter</span>.<span class="title function_">call</span>(vm, vm)</span><br><span class="line">    ...</span><br><span class="line">    <span class="keyword">return</span> value</span><br><span class="line">  &#125;</span><br><span class="line">  addDep (dep)&#123;</span><br><span class="line">        ...</span><br><span class="line">    dep.<span class="title function_">addSub</span>(<span class="variable language_">this</span>)</span><br><span class="line">  &#125;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="keyword">function</span> <span class="title function_">pushTarget</span> (_target) &#123;</span><br><span class="line">  <span class="title class_">Dep</span>.<span class="property">target</span> = _target</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><code>Watcher 是一个 class，它定义了一些方法，其中和依赖收集相关的主要有 get、addDep 等。</code></p>
<h4 id="过程"><a href="#过程" class="headerlink" title="过程"></a><strong>过程</strong></h4><p>在实例化 Vue 时，依赖收集的相关过程如下∶ 初 始 化 状 态 initState ， 这 中 间 便 会 通 过 defineReactive 将数据变成响应式对象，其中的 getter 部分便是用来依赖收集的。 初始化最终会走 mount 过程，其中会实例化 Watcher ，进入 Watcher 中，便会执行 this.get() 方法，</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">updateComponent = <span class="function">() =&gt;</span> &#123; vm.<span class="title function_">_update</span>(vm.<span class="title function_">_render</span>()) &#125; <span class="keyword">new</span> <span class="title class_">Watcher</span>(vm, updateComponent)</span><br></pre></td></tr></table></figure>


<blockquote>
<p><code>get 方法中的 pushTarget 实际上就是把 Dep.target 赋值为当前的 watcher。this.getter.call（vm，vm），这里的 getter 会执行 vm._render() 方法，在这个过程中便会触发数据对象的 getter。那么每个对象值的 getter 都持有一个 dep，在触发 getter 的时候会调用 dep.depend() 方法，也就会执行 Dep.target.addDep(this)。刚才 Dep.target 已经被赋值为 watcher，于是便会执行 addDep 方法，然后走到 dep.addSub() 方法，便将当前的 watcher 订阅到这个数据持有的 dep 的 subs 中，这个目的是为后续数据变化时候能通知到哪些 subs 做准备。所以在 vm._render() 过程中，会触发所有数据的 getter，这样便已经完成了一个依赖收集的过程。</code></p>
</blockquote>
<h3 id="25-对SSR的理解"><a href="#25-对SSR的理解" class="headerlink" title="25.对SSR的理解"></a>25.对SSR的理解</h3><p>SSR也就是服务端渲染，也就是将Vue在客户端把标签渲染成HTML的工作放在服务端完成，然后再把html直接返回给客户端</p>
<p>SSR的优势：</p>
<ul>
<li>更好的SEO</li>
<li>首屏加载速度更快</li>
</ul>
<p>SSR的缺点：</p>
<ul>
<li>开发条件会受到限制，服务器端渲染只支持beforeCreate和created两个钩子；</li>
<li>当需要一些外部扩展库时需要特殊处理，服务端渲染应用程序也需要处于Node.js的运行环境；</li>
<li>更多的服务端负载。</li>
</ul>
<h3 id="26-keep-alive-中的生命周期哪些"><a href="#26-keep-alive-中的生命周期哪些" class="headerlink" title="26.keep-alive 中的生命周期哪些"></a>26.keep-alive 中的生命周期哪些</h3><p>keep-alive是 Vue 提供的一个内置组件，用来对组件进行缓存——在组件切换过程中将状态保留在内存中，防止重复渲染DOM。</p>
<p>如果为一个组件包裹了 keep-alive，那么它会多出两个生命周期：deactivated、activated。同时，beforeDestroy 和 destroyed 就不会再被触发了，因为组件不会被真正销毁。</p>
<p>当组件被换掉时，会被缓存到内存中、触发 deactivated 生命周期；当组件被切回来时，再去缓存里找这个组件、触发 activated钩子函数。</p>
<h4 id="SEO优化"><a href="#SEO优化" class="headerlink" title="SEO优化"></a>SEO优化</h4><ul>
<li>预渲染</li>
<li>服务端渲染SSR</li>
</ul>
<h4 id="打包优化"><a href="#打包优化" class="headerlink" title="打包优化"></a>打包优化</h4><ul>
<li>压缩代码</li>
<li>Tree Shaking&#x2F;Scope Hoisting</li>
<li>使用cdn加载第三方模块</li>
<li>多线程打包happypack</li>
<li>splitChunks抽离公共文件</li>
<li>sourceMap优化</li>
</ul>
<h2 id="vue项目遇到的问题"><a href="#vue项目遇到的问题" class="headerlink" title="vue项目遇到的问题"></a>vue项目遇到的问题</h2><h3 id="1-在开发过程中，如果你的-Vue-程序和后端-API-服务器未在同一主机上运行，该如何代理-API-请求。假设使用-Vue-CLI-3-进行设置？"><a href="#1-在开发过程中，如果你的-Vue-程序和后端-API-服务器未在同一主机上运行，该如何代理-API-请求。假设使用-Vue-CLI-3-进行设置？" class="headerlink" title="1 .在开发过程中，如果你的 Vue 程序和后端 API 服务器未在同一主机上运行，该如何代理 API 请求。假设使用 Vue-CLI 3 进行设置？"></a>1 .在开发过程中，如果你的 Vue 程序和后端 API 服务器未在同一主机上运行，该如何代理 API 请求。假设使用 Vue-CLI 3 进行设置？</h3><p>   在 vue.config.js 文件中：<br>   <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">   <span class="variable language_">module</span>.<span class="property">exports</span>: &#123;</span><br><span class="line">    <span class="attr">devServer</span>: &#123;</span><br><span class="line">        <span class="attr">proxy</span>: &#123;</span><br><span class="line">            <span class="string">&#x27;/api&#x27;</span>: &#123; </span><br><span class="line">                <span class="attr">target</span>: ‘<span class="attr">http</span>:<span class="comment">//localhost:4040/api’, </span></span><br><span class="line">                <span class="attr">changeOrigin</span>: <span class="literal">true</span> </span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<h3 id="2-prop-如何指定其类型要求？"><a href="#2-prop-如何指定其类型要求？" class="headerlink" title="2. prop 如何指定其类型要求？"></a>2. prop 如何指定其类型要求？</h3><pre><code>通过实现 prop 验证选项，可以为单个 prop 指定类型要求。这对生产没有影响，但是会在开发阶段发出警告，从而帮助开发人员识别传入数据和 prop 的特定类型要求的潜在问题。
</code></pre>
 <figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">    <span class="attr">props</span>: &#123;</span><br><span class="line">    <span class="attr">accountNumber</span>: &#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="title class_">Number</span>,</span><br><span class="line">        <span class="attr">required</span>: <span class="literal">true</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">name</span>: &#123;</span><br><span class="line">        <span class="attr">type</span>: <span class="title class_">String</span>,</span><br><span class="line">        <span class="attr">required</span>: <span class="literal">true</span></span><br><span class="line">   &#125;,</span><br><span class="line">   <span class="attr">favoriteColors</span>: <span class="title class_">Array</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="26-组件通信"><a href="#26-组件通信" class="headerlink" title="26.组件通信"></a>26.组件通信</h3><p>组件通信的方式如下：</p>
<h3 id="（1）-props-x2F-emit"><a href="#（1）-props-x2F-emit" class="headerlink" title="（1） props  &#x2F;   $emit"></a>（1） props  &#x2F;   $emit</h3><p>父组件通过<code>props</code>向子组件传递数据，子组件通过<code>$emit</code>和父组件通信</p>
<h5 id="1-父组件向子组件传值"><a href="#1-父组件向子组件传值" class="headerlink" title="1. 父组件向子组件传值"></a>1. 父组件向子组件传值</h5><ul>
<li><code>props</code>只能是父组件向子组件进行传值，<code>props</code>使得父子组件之间形成了一个单向下行绑定。子组件的数据会随着父组件不断更新。</li>
<li><code>props</code> 可以显示定义一个或一个以上的数据，对于接收的数据，可以是各种数据类型，同样也可以传递一个函数。</li>
<li><code>props</code>属性名规则：若在<code>props</code>中使用驼峰形式，模板中需要使用短横线的形式<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 父组件</span></span><br><span class="line">&lt;template&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;father&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">son</span> <span class="attr">:msg</span>=<span class="string">&quot;msgData&quot;</span> <span class="attr">:fn</span>=<span class="string">&quot;myFunction&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">son</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> son <span class="keyword">from</span> <span class="string">&quot;./son.vue&quot;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">name</span>: father,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">msgData</span>: <span class="string">&quot;父组件数据&quot;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="title function_">myFunction</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&quot;vue&quot;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">components</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        son</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 子组件</span></span><br><span class="line">&lt;template&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;son&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;&#123;msg&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;fn&quot;</span>&gt;</span>按钮<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">name</span>: <span class="string">&quot;son&quot;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">props</span>: [<span class="string">&quot;msg&quot;</span>, <span class="string">&quot;fn&quot;</span>]</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure></li>
</ul>
<h5 id="子组件向父组件传值"><a href="#子组件向父组件传值" class="headerlink" title="子组件向父组件传值"></a>子组件向父组件传值</h5><ul>
<li><code>$emit</code>绑定一个自定义事件，当这个事件被执行的时就会将参数传递给父组件，而父组件通过<code>v-on</code>监听并接收参数。<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 父组件</span></span><br><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;section&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">com-article</span> <span class="attr">:articles</span>=<span class="string">&quot;articleList&quot;</span> @<span class="attr">onEmitIndex</span>=<span class="string">&quot;onEmitIndex&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">com-article</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">p</span>&gt;</span>&#123;&#123;currentIndex&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> comArticle <span class="keyword">from</span> <span class="string">&#x27;./test/article.vue&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">name</span>: <span class="string">&#x27;comArticle&#x27;</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">components</span>: &#123; comArticle &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">currentIndex</span>: -<span class="number">1</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">articleList</span>: [<span class="string">&#x27;红楼梦&#x27;</span>, <span class="string">&#x27;西游记&#x27;</span>, <span class="string">&#x27;三国演义&#x27;</span>]</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">onEmitIndex</span>(<span class="params">idx</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">currentIndex</span> = idx</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure></li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">/子组件</span><br><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">v-for</span>=<span class="string">&quot;(item, index) in articles&quot;</span> <span class="attr">:key</span>=<span class="string">&quot;index&quot;</span> @<span class="attr">click</span>=<span class="string">&quot;emitIndex(index)&quot;</span>&gt;</span>&#123;&#123;item&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">props</span>: [<span class="string">&#x27;articles&#x27;</span>],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">emitIndex</span>(<span class="params">index</span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.$emit(<span class="string">&#x27;onEmitIndex&#x27;</span>, index) <span class="comment">// 触发父组件的方法，并传递参数index</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<h3 id="eventBus事件总线（-emit-on）"><a href="#eventBus事件总线（-emit-on）" class="headerlink" title="eventBus事件总线（$emit / $on）"></a>eventBus事件总线（<code>$emit / $on</code>）</h3><p><code>eventBus</code>事件总线适用于<strong>父子组件</strong>、<strong>非父子组件</strong>等之间的通信，使用步骤如下：  <strong>（1）创建事件中心管理组件之间的通信</strong></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// event-bus.js</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> <span class="title class_">Vue</span> <span class="keyword">from</span> <span class="string">&#x27;vue&#x27;</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> <span class="title class_">EventBus</span> = <span class="keyword">new</span> <span class="title class_">Vue</span>()</span><br></pre></td></tr></table></figure>
<p><strong>发送事件</strong> 假设有两个兄弟组件<code>firstCom</code>和<code>secondCom</code>：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">first-com</span>&gt;</span><span class="tag">&lt;/<span class="name">first-com</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">second-com</span>&gt;</span><span class="tag">&lt;/<span class="name">second-com</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> firstCom <span class="keyword">from</span> <span class="string">&#x27;./firstCom.vue&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> secondCom <span class="keyword">from</span> <span class="string">&#x27;./secondCom.vue&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">components</span>: &#123; firstCom, secondCom &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>在<code>firstCom</code>组件中发送事件：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;<span class="name">button</span> @<span class="attr">click</span>=<span class="string">&quot;add&quot;</span>&gt;</span>加法<span class="tag">&lt;/<span class="name">button</span>&gt;</span>    </span></span><br><span class="line"><span class="language-xml">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123;<span class="title class_">EventBus</span>&#125; <span class="keyword">from</span> <span class="string">&#x27;./event-bus.js&#x27;</span> <span class="comment">// 引入事件中心</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>)&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span>&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">num</span>:<span class="number">0</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="attr">methods</span>:&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">add</span>(<span class="params"></span>)&#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="title class_">EventBus</span>.$emit(<span class="string">&#x27;addition&#x27;</span>, &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="attr">num</span>:<span class="variable language_">this</span>.<span class="property">num</span>++</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p><strong>接收事件</strong> 在<code>secondCom</code>组件中发送事件：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">  <span class="language-xml"><span class="tag">&lt;<span class="name">div</span>&gt;</span>求和: &#123;&#123;count&#125;&#125;<span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"></span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> &#123; <span class="title class_">EventBus</span> &#125; <span class="keyword">from</span> <span class="string">&#x27;./event-bus.js&#x27;</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">data</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="keyword">return</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="attr">count</span>: <span class="number">0</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  <span class="title function_">mounted</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title class_">EventBus</span>.$on(<span class="string">&#x27;addition&#x27;</span>, <span class="function"><span class="params">param</span> =&gt;</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">      <span class="variable language_">this</span>.<span class="property">count</span> = <span class="variable language_">this</span>.<span class="property">count</span> + param.<span class="property">num</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;)</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">  &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>在上述代码中，这就相当于将<code>num</code>值存贮在了事件总线中，在其他组件中可以直接访问。事件总线就相当于一个桥梁，不用组件通过它来通信。</p>
</blockquote>
<blockquote>
<p>虽然看起来比较简单，但是这种方法也有不变之处，如果项目过大，使用这种方式进行通信，后期维护起来会很困难</p>
</blockquote>
<h3 id="依赖注入（provide-x2F-inject）"><a href="#依赖注入（provide-x2F-inject）" class="headerlink" title="依赖注入（provide &#x2F; inject）"></a>依赖注入（provide &#x2F; inject）</h3><p>这种方式就是Vue中的<strong>依赖注入</strong>，该方法用于<strong>父子组件之间的通信</strong>。当然这里所说的父子不一定是真正的父子，也可以是祖孙组件，在层数很深的情况下，可以使用这种方法来进行传值。就不用一层一层的传递了。<br><code>provide / inject</code>是Vue提供的两个钩子，和<code>data</code>、<code>methods</code>是同级的。并且<code>provide</code>的书写形式和<code>data</code>一样。</p>
<ul>
<li><code>provide</code> 钩子用来发送数据或方法</li>
<li><code>inject</code>钩子用来接收数据或方法<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//父</span></span><br><span class="line"><span class="title function_">provide</span>(<span class="params"></span>) &#123; <span class="keyword">return</span> &#123; <span class="attr">num</span>: <span class="variable language_">this</span>.<span class="property">num</span> &#125;; &#125;</span><br><span class="line"><span class="comment">//子</span></span><br><span class="line"><span class="attr">inject</span>: [<span class="string">&#x27;num&#x27;</span>]</span><br></pre></td></tr></table></figure>
<strong><code>依赖注入所提供的属性是非响应式的。</code></strong></li>
</ul>
<h3 id="parent-x2F-children"><a href="#parent-x2F-children" class="headerlink" title="$parent &#x2F; $children"></a>$parent &#x2F; $children</h3><ul>
<li>使用<code>$parent</code>可以让组件访问父组件的实例（访问的是上一级父组件的属性和方法）</li>
<li>使用<code>$children</code>可以让组件访问子组件的实例，但是，<code>$children</code>并不能保证顺序，并且访问的数据也不是响应式的。</li>
</ul>
<h3 id="attrs-listeners"><a href="#attrs-listeners" class="headerlink" title="$attrs / $listeners"></a><code>$attrs / $listeners</code></h3><p>考虑一种场景，如果A是B组件的父组件，B是C组件的父组件。如果想要组件A给组件C传递数据，这种隔代的数据，该使用哪种方式呢？</p>
<p>如果是用<code>props/$emit</code>来一级一级的传递，确实可以完成，但是比较复杂；如果使用事件总线，在多人开发或者项目较大的时候，维护起来很麻烦；如果使用Vuex，的确也可以，但是如果仅仅是传递数据，那可能就有点浪费了。</p>
<p>针对上述情况，Vue引入了<code>$attrs / $listeners</code>，实现组件之间的跨代通信。</p>
<p>先来看一下<code>inheritAttrs</code>，它的默认值true，继承所有的父组件属性除<code>props</code>之外的所有属性；<code>inheritAttrs：false</code> 只继承class属性 。</p>
<ul>
<li><code>$attrs</code>：继承所有的父组件属性（除了prop传递的属性、class 和 style ），一般用在子组件的子元素上</li>
<li><code>$listeners</code>：该属性是一个对象，里面包含了作用在这个组件上的所有监听器，可以配合 <code>v-on=&quot;$listeners&quot;</code> 将所有的事件监听器指向这个组件的某个特定的子元素。（相当于子组件继承父组件的事件）</li>
</ul>
<p>A组件（<code>APP.vue</code>）：</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">id</span>=<span class="string">&quot;app&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        //此处监听了两个事件，可以在B组件或者C组件中直接触发 </span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">child1</span> <span class="attr">:p-child1</span>=<span class="string">&quot;child1&quot;</span> <span class="attr">:p-child2</span>=<span class="string">&quot;child2&quot;</span> @<span class="attr">test1</span>=<span class="string">&quot;onTest1&quot;</span> @<span class="attr">test2</span>=<span class="string">&quot;onTest2&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">child1</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> <span class="title class_">Child1</span> <span class="keyword">from</span> <span class="string">&#x27;./Child1.vue&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">components</span>: &#123; <span class="title class_">Child1</span> &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">methods</span>: &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="title function_">onTest1</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;test1 running&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="title function_">onTest2</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">            <span class="variable language_">console</span>.<span class="title function_">log</span>(<span class="string">&#x27;test2 running&#x27;</span>);</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>B组件（<code>Child1.vue</code>）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;child-1&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>props: &#123;&#123;pChild1&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>$attrs: &#123;&#123;$attrs&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">child2</span> <span class="attr">v-bind</span>=<span class="string">&quot;$attrs&quot;</span> <span class="attr">v-on</span>=<span class="string">&quot;$listeners&quot;</span>&gt;</span><span class="tag">&lt;/<span class="name">child2</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">import</span> <span class="title class_">Child2</span> <span class="keyword">from</span> <span class="string">&#x27;./Child2.vue&#x27;</span>;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">props</span>: [<span class="string">&#x27;pChild1&#x27;</span>],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">components</span>: &#123; <span class="title class_">Child2</span> &#125;,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">inheritAttrs</span>: <span class="literal">false</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">mounted</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">this</span>.$emit(<span class="string">&#x27;test1&#x27;</span>); <span class="comment">// 触发APP.vue中的test1方法</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>C 组件 (<code>Child2.vue</code>):</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">&lt;template&gt;</span><br><span class="line">    <span class="language-xml"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;child-2&quot;</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>props: &#123;&#123;pChild2&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>$attrs: &#123;&#123;$attrs&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span></span><br><span class="line"><span class="language-xml">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span></span><br><span class="line">&lt;/template&gt;</span><br><span class="line"><span class="language-xml"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="language-javascript"></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">props</span>: [<span class="string">&#x27;pChild2&#x27;</span>],</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="attr">inheritAttrs</span>: <span class="literal">false</span>,</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    <span class="title function_">mounted</span>(<span class="params"></span>) &#123;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">        <span class="variable language_">this</span>.$emit(<span class="string">&#x27;test2&#x27;</span>);<span class="comment">// 触发APP.vue中的test2方法</span></span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">    &#125;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml">&#125;;</span></span></span><br><span class="line"><span class="language-javascript"><span class="language-xml"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span></span><br></pre></td></tr></table></figure>
<p>在上述代码中：</p>
<ul>
<li>C组件中能直接触发test的原因在于 B组件调用C组件时 使用 v-on 绑定了<code>$listeners</code> 属性</li>
<li>在B组件中通过v-bind 绑定<code>$attrs</code>属性，C组件可以直接获取到A组件中传递下来的props（除了B组件中props声明的）</li>
</ul>
<p><strong>Vue和React的区别</strong></p>
<p>相同点：</p>
<ul>
<li>1.都使用了虚拟dom</li>
<li>2.组件化开发</li>
<li>3.都是单向数据流(父子组件之间，不建议子修改父传下来的数据)</li>
<li>4.都支持服务端渲染</li>
</ul>
<p>不同点：</p>
<ul>
<li>1.React的JSX，Vue的template</li>
<li>2.数据变化，React手动(setState)，Vue自动(初始化已响应式处理，Object.defineProperty)</li>
<li>3.React单向绑定，Vue双向绑定</li>
<li>4.React的Redux，Vue的Vuex</li>
</ul>
</article><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/my-hexo-blog/tags/%E9%9D%A2%E8%AF%95/">面试</a></div><div class="post_share"></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/my-hexo-blog/2021/06/01/Design/"><img class="prev-cover" src="/my-hexo-blog/img/1.png" onerror="onerror=null;src='/my-hexo-blog/img/404.jpg'" alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">最常用的8大JavaScript设计模式，助你提高代码性能</div></div></a></div><div class="next-post pull-right"><a href="/my-hexo-blog/2021/01/15/react/"><img class="next-cover" src="/my-hexo-blog/img/react.png" onerror="onerror=null;src='/my-hexo-blog/img/404.jpg'" alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">react入门基础篇</div></div></a></div></nav></div><div class="aside-content" id="aside-content"><div class="card-widget card-info"><div class="is-center"><div class="avatar-img"><img src="/my-hexo-blog/img/2.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/friend_404.gif'" alt="avatar"/></div><div class="author-info__name">william</div><div class="author-info__description"> 青山不改，绿水长流</div></div><div class="card-info-data site-data is-center"><a href="/my-hexo-blog/archives/"><div class="headline">文章</div><div class="length-num">17</div></a><a href="/my-hexo-blog/tags/"><div class="headline">标签</div><div class="length-num">13</div></a><a href="/my-hexo-blog/categories/"><div class="headline">分类</div><div class="length-num">0</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/yokeney"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons is-center"><a class="social-icon" href="https://github.com/yokeney" target="_blank" title="Github"><i class="fab fa-github"></i></a><a class="social-icon" href="/my-hexo-blog/965660471@qq.com" target="_blank" title="Email"><i class="fas fa-envelope"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">加油</div></div><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E4%BB%80%E4%B9%88%E6%98%AF-MVVM%EF%BC%9F"><span class="toc-number">1.</span> <span class="toc-text">1. 什么是 MVVM？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-%E7%BB%84%E4%BB%B6%E9%80%9A%E8%AE%AF"><span class="toc-number">2.</span> <span class="toc-text">2.组件通讯</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%88%B6%E4%BC%A0%E5%AD%90"><span class="toc-number">2.1.</span> <span class="toc-text">父传子</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AD%90%E4%BC%A0%E7%88%B6"><span class="toc-number">2.2.</span> <span class="toc-text">子传父</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%9D%9E%E7%88%B6%E5%AD%90"><span class="toc-number">2.3.</span> <span class="toc-text">非父子</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#vuex"><span class="toc-number">2.4.</span> <span class="toc-text">vuex</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#3-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F"><span class="toc-number">3.</span> <span class="toc-text">3.生命周期</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#4-vue%E7%BB%84%E4%BB%B6%E4%B8%ADdata%E5%BF%85%E9%A1%BB%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0"><span class="toc-number">4.</span> <span class="toc-text">4.vue组件中data必须是一个函数</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#5-Vue-%E4%B8%AD-v-if-%E5%92%8C-v-show-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-number">5.</span> <span class="toc-text">5.Vue 中 v-if 和 v-show 有什么区别？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#6-Vue-%E4%B8%AD-computed-%E5%92%8C-watch-%E6%9C%89%E4%BB%80%E4%B9%88%E5%8C%BA%E5%88%AB%EF%BC%9F"><span class="toc-number">6.</span> <span class="toc-text">6.Vue 中 computed 和 watch 有什么区别？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#7-nextTick-%E6%98%AF%E4%BB%80%E4%B9%88"><span class="toc-number">7.</span> <span class="toc-text">7.$nextTick 是什么</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#8-v-for-%E4%B8%AD-key-%E7%9A%84%E4%BD%9C%E7%94%A8%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F"><span class="toc-number">8.</span> <span class="toc-text">8. v-for 中 key 的作用是什么？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#9-Vue-%E7%9A%84%E5%8F%8C%E5%90%91%E6%95%B0%E6%8D%AE%E7%BB%91%E5%AE%9A%E5%8E%9F%E7%90%86%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F"><span class="toc-number">9.</span> <span class="toc-text">9. Vue 的双向数据绑定原理是什么？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#10-%E5%A6%82%E4%BD%95%E5%8A%A8%E6%80%81%E6%9B%B4%E6%96%B0%E5%AF%B9%E8%B1%A1%E6%88%96%E6%95%B0%E7%BB%84%E7%9A%84%E5%80%BC%EF%BC%9F"><span class="toc-number">10.</span> <span class="toc-text">10.如何动态更新对象或数组的值？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#11-%E5%B8%B8%E7%94%A8%E7%9A%84%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6%E6%9C%89%E5%93%AA%E4%BA%9B%EF%BC%9F"><span class="toc-number">11.</span> <span class="toc-text">11.常用的事件修饰符有哪些？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#12-Vue-%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96-DOM-%E5%85%83%E7%B4%A0%EF%BC%9F"><span class="toc-number">12.</span> <span class="toc-text">12.Vue 如何获取 DOM 元素？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#13-v-on-%E5%A6%82%E4%BD%95%E7%BB%91%E5%AE%9A%E5%A4%9A%E4%B8%AA%E4%BA%8B%E4%BB%B6%EF%BC%9F"><span class="toc-number">13.</span> <span class="toc-text">13.v-on 如何绑定多个事件？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#14-Vue-%E5%88%9D%E5%A7%8B%E5%8C%96%E9%A1%B5%E9%9D%A2%E9%97%AA%E5%8A%A8%E9%97%AE%E9%A2%98%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%EF%BC%9F"><span class="toc-number">14.</span> <span class="toc-text">14.Vue 初始化页面闪动问题如何解决？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#15-Vue-%E5%A6%82%E4%BD%95%E6%B8%85%E9%99%A4%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98%EF%BC%9F"><span class="toc-number">15.</span> <span class="toc-text">15.Vue 如何清除浏览器缓存？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#16-Vue-router-%E8%B7%AF%E7%94%B1%E6%9C%89%E5%93%AA%E4%BA%9B%E6%A8%A1%E5%BC%8F%EF%BC%9F"><span class="toc-number">16.</span> <span class="toc-text">16.Vue-router 路由有哪些模式？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#18-Vuex-%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%E6%9C%89%E5%93%AA%E5%87%A0%E7%A7%8D%E5%B1%9E%E6%80%A7%EF%BC%9F"><span class="toc-number">17.</span> <span class="toc-text">18.Vuex 是什么？有哪几种属性？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#19-%E8%AF%B4%E4%B8%80%E4%B8%8Bv-model%E7%9A%84%E5%8E%9F%E7%90%86"><span class="toc-number">18.</span> <span class="toc-text">19.说一下v-model的原理</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#20-Vue%E6%A8%A1%E7%89%88%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86%E7%9F%A5%E9%81%93%E5%90%97%EF%BC%8C%E8%83%BD%E7%AE%80%E5%8D%95%E8%AF%B4%E4%B8%80%E4%B8%8B%E5%90%97%EF%BC%9F"><span class="toc-number">19.</span> <span class="toc-text">20.Vue模版编译原理知道吗，能简单说一下吗？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#21-Vue%E4%B8%AD%E7%BB%84%E4%BB%B6%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E8%B0%83%E7%94%A8%E9%A1%BA%E5%BA%8F"><span class="toc-number">20.</span> <span class="toc-text">21.Vue中组件生命周期调用顺序</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8A%A0%E8%BD%BD%E6%B8%B2%E6%9F%93%E8%BF%87%E7%A8%8B"><span class="toc-number">20.1.</span> <span class="toc-text">加载渲染过程</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AD%90%E7%BB%84%E4%BB%B6%E6%9B%B4%E6%96%B0%E8%BF%87%E7%A8%8B"><span class="toc-number">20.2.</span> <span class="toc-text">子组件更新过程</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E9%94%80%E6%AF%81%E8%BF%87%E7%A8%8B"><span class="toc-number">20.3.</span> <span class="toc-text">销毁过程</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#vue-router%E6%9C%89%E5%93%AA%E5%87%A0%E7%A7%8D%E5%AF%BC%E8%88%AA%E9%92%A9%E5%AD%90%EF%BC%9F"><span class="toc-number"></span> <span class="toc-text">vue-router有哪几种导航钩子？</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#22-%E4%BD%A0%E9%83%BD%E5%81%9A%E8%BF%87%E5%93%AA%E4%BA%9BVue%E7%9A%84%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96"><span class="toc-number">1.</span> <span class="toc-text">22.你都做过哪些Vue的性能优化</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%BC%96%E7%A0%81%E9%98%B6%E6%AE%B5"><span class="toc-number">1.1.</span> <span class="toc-text">编码阶段</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#24-Vue%E6%98%AF%E5%A6%82%E4%BD%95%E6%94%B6%E9%9B%86%E4%BE%9D%E8%B5%96%E7%9A%84%EF%BC%9F"><span class="toc-number">2.</span> <span class="toc-text">24.Vue是如何收集依赖的？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Watcher"><span class="toc-number">3.</span> <span class="toc-text">Watcher</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E8%BF%87%E7%A8%8B"><span class="toc-number">3.1.</span> <span class="toc-text">过程</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#25-%E5%AF%B9SSR%E7%9A%84%E7%90%86%E8%A7%A3"><span class="toc-number">4.</span> <span class="toc-text">25.对SSR的理解</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#26-keep-alive-%E4%B8%AD%E7%9A%84%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%93%AA%E4%BA%9B"><span class="toc-number">5.</span> <span class="toc-text">26.keep-alive 中的生命周期哪些</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#SEO%E4%BC%98%E5%8C%96"><span class="toc-number">5.1.</span> <span class="toc-text">SEO优化</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%89%93%E5%8C%85%E4%BC%98%E5%8C%96"><span class="toc-number">5.2.</span> <span class="toc-text">打包优化</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#vue%E9%A1%B9%E7%9B%AE%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98"><span class="toc-number"></span> <span class="toc-text">vue项目遇到的问题</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#1-%E5%9C%A8%E5%BC%80%E5%8F%91%E8%BF%87%E7%A8%8B%E4%B8%AD%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E7%9A%84-Vue-%E7%A8%8B%E5%BA%8F%E5%92%8C%E5%90%8E%E7%AB%AF-API-%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%9C%AA%E5%9C%A8%E5%90%8C%E4%B8%80%E4%B8%BB%E6%9C%BA%E4%B8%8A%E8%BF%90%E8%A1%8C%EF%BC%8C%E8%AF%A5%E5%A6%82%E4%BD%95%E4%BB%A3%E7%90%86-API-%E8%AF%B7%E6%B1%82%E3%80%82%E5%81%87%E8%AE%BE%E4%BD%BF%E7%94%A8-Vue-CLI-3-%E8%BF%9B%E8%A1%8C%E8%AE%BE%E7%BD%AE%EF%BC%9F"><span class="toc-number">1.</span> <span class="toc-text">1 .在开发过程中，如果你的 Vue 程序和后端 API 服务器未在同一主机上运行，该如何代理 API 请求。假设使用 Vue-CLI 3 进行设置？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#2-prop-%E5%A6%82%E4%BD%95%E6%8C%87%E5%AE%9A%E5%85%B6%E7%B1%BB%E5%9E%8B%E8%A6%81%E6%B1%82%EF%BC%9F"><span class="toc-number">2.</span> <span class="toc-text">2. prop 如何指定其类型要求？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#26-%E7%BB%84%E4%BB%B6%E9%80%9A%E4%BF%A1"><span class="toc-number">3.</span> <span class="toc-text">26.组件通信</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%EF%BC%881%EF%BC%89-props-x2F-emit"><span class="toc-number">4.</span> <span class="toc-text">（1） props  &#x2F;   $emit</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#1-%E7%88%B6%E7%BB%84%E4%BB%B6%E5%90%91%E5%AD%90%E7%BB%84%E4%BB%B6%E4%BC%A0%E5%80%BC"><span class="toc-number">4.0.1.</span> <span class="toc-text">1. 父组件向子组件传值</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%AD%90%E7%BB%84%E4%BB%B6%E5%90%91%E7%88%B6%E7%BB%84%E4%BB%B6%E4%BC%A0%E5%80%BC"><span class="toc-number">4.0.2.</span> <span class="toc-text">子组件向父组件传值</span></a></li></ol></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#eventBus%E4%BA%8B%E4%BB%B6%E6%80%BB%E7%BA%BF%EF%BC%88-emit-on%EF%BC%89"><span class="toc-number">5.</span> <span class="toc-text">eventBus事件总线（$emit &#x2F; $on）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%EF%BC%88provide-x2F-inject%EF%BC%89"><span class="toc-number">6.</span> <span class="toc-text">依赖注入（provide &#x2F; inject）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#parent-x2F-children"><span class="toc-number">7.</span> <span class="toc-text">$parent &#x2F; $children</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#attrs-listeners"><span class="toc-number">8.</span> <span class="toc-text">$attrs &#x2F; $listeners</span></a></li></ol></div></div><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/05/26/VUE3%E9%9B%86%E6%88%90%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%90%8E%E5%8F%B0%E9%80%9A%E7%94%A8%E8%A7%84%E8%8C%83%E6%A8%A1%E7%89%88/" title="VUE3集成企业级后台通用规范模版"><img src="/my-hexo-blog/img/1.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="VUE3集成企业级后台通用规范模版"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/05/26/VUE3%E9%9B%86%E6%88%90%E4%BC%81%E4%B8%9A%E7%BA%A7%E5%90%8E%E5%8F%B0%E9%80%9A%E7%94%A8%E8%A7%84%E8%8C%83%E6%A8%A1%E7%89%88/" title="VUE3集成企业级后台通用规范模版">VUE3集成企业级后台通用规范模版</a><time datetime="2023-05-26T13:17:48.000Z" title="发表于 2023-05-26 21:17:48">2023-05-26</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E6%B2%A1%E7%9C%8B%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%B9%8B%E5%89%8D%E5%8E%9F%E6%9D%A5%E6%88%91%E5%AF%B9react18%E4%B8%80%E7%9F%A5%E5%8D%8A%E8%A7%A3/" title="没看这篇文章之前原来我对react18一知半解"><img src="/my-hexo-blog/img/react.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="没看这篇文章之前原来我对react18一知半解"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E6%B2%A1%E7%9C%8B%E8%BF%99%E7%AF%87%E6%96%87%E7%AB%A0%E4%B9%8B%E5%89%8D%E5%8E%9F%E6%9D%A5%E6%88%91%E5%AF%B9react18%E4%B8%80%E7%9F%A5%E5%8D%8A%E8%A7%A3/" title="没看这篇文章之前原来我对react18一知半解">没看这篇文章之前原来我对react18一知半解</a><time datetime="2023-04-24T09:11:02.000Z" title="发表于 2023-04-24 17:11:02">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%85%A8Vue3%E6%80%BB%E7%BB%93/" title="史上最全Vue3总结"><img src="/my-hexo-blog/img/1.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="史上最全Vue3总结"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%85%A8Vue3%E6%80%BB%E7%BB%93/" title="史上最全Vue3总结">史上最全Vue3总结</a><time datetime="2023-04-24T09:01:19.000Z" title="发表于 2023-04-24 17:01:19">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2023/04/24/%E4%B8%8EReact18%E7%9A%84%E5%8C%BA%E5%88%AB%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/" title="Vue与React18的区别深度解析"><img src="/my-hexo-blog/img/vue_vs-react.png" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="Vue与React18的区别深度解析"/></a><div class="content"><a class="title" href="/my-hexo-blog/2023/04/24/%E4%B8%8EReact18%E7%9A%84%E5%8C%BA%E5%88%AB%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90/" title="Vue与React18的区别深度解析">Vue与React18的区别深度解析</a><time datetime="2023-04-24T08:39:32.000Z" title="发表于 2023-04-24 16:39:32">2023-04-24</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/my-hexo-blog/2022/10/25/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%86%99%E4%B8%80%E4%B8%AAbabel/" title="手把手教你写babel插件"><img src="/my-hexo-blog/img/babel.webp" onerror="this.onerror=null;this.src='/my-hexo-blog/img/404.jpg'" alt="手把手教你写babel插件"/></a><div class="content"><a class="title" href="/my-hexo-blog/2022/10/25/%E6%89%8B%E6%8A%8A%E6%89%8B%E5%B8%A6%E4%BD%A0%E5%86%99%E4%B8%80%E4%B8%AAbabel/" title="手把手教你写babel插件">手把手教你写babel插件</a><time datetime="2022-10-25T01:10:14.000Z" title="发表于 2022-10-25 09:10:14">2022-10-25</time></div></div></div></div></div></div></main><footer id="footer" style="background-image: url('/my-hexo-blog/img/1.png')"><div id="footer-wrap"><div class="copyright">&copy;2018 - 2023 By william</div><div class="footer_custom_text">关山难越，谁悲失路之人</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></div><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><span id="loading-status"></span><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="is-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span>  数据库加载中</span></div><div class="search-wrap"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div><hr/><div id="local-search-results"></div></div></div><div id="search-mask"></div></div><div><script src="/my-hexo-blog/js/utils.js"></script><script src="/my-hexo-blog/js/main.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui/dist/fancybox.umd.min.js"></script><script src="/my-hexo-blog/js/search/local-search.js"></script><div class="js-pjax"></div><div class="aplayer no-destroy" data-id="22712173" data-server="netease" data-mini="true" data-type="song" data-autoplay="false" data-lrcType="-1"> </div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc/metingjs/dist/Meting.min.js"></script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div></body></html>